package org.swift.mashup.engine.model.processors;

import org.apache.axiom.om.OMElement;
import org.jaxen.JaxenException;
import org.swift.commons.xml.OMUtils;
import org.swift.commons.xml.TransformUtils;
import org.swift.commons.xml.XmlUtils;
import org.swift.mashup.engine.model.ActivityContext;
import org.swift.mashup.engine.model.ByteArrayActivityContext;

import javax.xml.stream.XMLStreamException;
import javax.xml.transform.TransformerException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;

public class DelimitedTextToXmlProcessor implements FromProcessor {
	private static String STYLESHEET = "/org/swift/mashup/engine/model/processors/csvToXml.xsl";

	private final String delimiter;

	DelimitedTextToXmlProcessor(String delimiter) {
		this.delimiter = delimiter;
	}

	/**
	 * Takes delimited data and transforms it into simple xml. The format will be as follows:<br><br>
	 * <b>&lt;root&gt;<br>
	 * &nbsp;&nbsp;&nbsp;&lt;row&gt;<br>
	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;elem name="ColName 1"&gt;value 1&lt;/elem&gt;<br>
	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;elem name="ColName 2"&gt;value 2&lt;/elem&gt;<br>
	 * &nbsp;&nbsp;&nbsp;&lt;/row&gt;<br>
	 * &lt;/root&gt;</b><br>
	 */
	public ActivityContext processData(ActivityContext data) {
		try {
			String dataAsString = new String(data.getBytes());
			if (!XmlUtils.isXml(dataAsString)){
				dataAsString = XmlUtils.toXML(dataAsString);
			}
			InputStream is = getClass().getResourceAsStream(STYLESHEET);
			OMElement source = OMUtils.stringToOMElement(dataAsString);
			OMElement stylesheet = OMUtils.streamToOMElement(is);
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			Map<String,String> parameters = Collections.singletonMap("delimiter", delimiter);
			TransformUtils.transformToStream(output, parameters,
					TransformUtils.omElementToSource(source),
					TransformUtils.omElementToSource(stylesheet)
			);
			return new ByteArrayActivityContext(output.toByteArray());
		} catch (IOException e) {
			throw new RuntimeException("Error processing data",e);
		} catch (TransformerException e) {
			throw new RuntimeException("Error transforming data",e);
		} catch (XMLStreamException e) {
			throw new RuntimeException("Error streaming xsl",e);
		} catch (JaxenException e) {
			throw new RuntimeException("Error preparing transformation",e);
		}
	}
}
